#include "gps_leg.h"

QColor base_colors[] = { QColor( 0,255,0 ), // 2 -green
                    QColor( 255,0,0 ), // 3 -red
                    QColor( 0,0,255 ), // 4 -blue
                    QColor( 128,128,128 ), // 5 -gray
                    QColor( 0,255,255), // 6 -cyan
                    QColor( 255,0,255), // 7 - yellow
                    QColor( 255,255,0), // 8 - purple
                    QColor( 255,255,255 ) // 1 -white
                           };

GPS_leg::GPS_leg() :
    Modifiable()
{
    static int next_legs_color = 0;
    static int global_legs_id = 0;

    _id = global_legs_id++;
    _title = QString( QObject::tr("Leg n.") + "%1").arg( _id );
    length_mt = 0;
    _boundingRect = QRectF(0,0,0,0);
    _color = base_colors[ next_legs_color++ ];
    if ( next_legs_color > MAX_BASE_COLOR )
        next_legs_color = 0;
}

GPS_leg::GPS_leg(const GPS_leg&) :
    Modifiable()
{
    while(1);
}

GPS_leg::~GPS_leg()
{
    foreach ( GPS_point* pt, _points )
        delete pt;
}

int GPS_leg::id() const
{
    return _id;
}

QString GPS_leg::title() const
{
    return _title;
}

void GPS_leg::setTitle(const QString& t)
{
    if ( t != _title )
    {
        Modify();
        _title = t;
    }
}

QColor GPS_leg::color() const
{
    return _color;
}

void GPS_leg::setColor(const QColor& c)
{
    if ( c != _color )
    {
        Modify();
        _color = c;
    }
}

void GPS_leg::addPoint(GPS_point* npt)
{
    if ( _points.count() > 0 )
        length_mt += npt->distanceTo( *_points.last() );
    _points.append( npt );
    _quickPoints.append( QPointF( npt->longitude(), npt->latitude() ));
    expandBoundingRect( npt->latitude(), npt->longitude() );
}

const GPS_point* GPS_leg::point(int i) const
{
    if ( (i > -1 ) && ( i < _points.count() ) )
        return _points.at(i);
    return NULL;
}

QPointF GPS_leg::quickPoint(int i) const
{
    if ( (i > -1 ) && ( i < _quickPoints.count() ) )
        return _quickPoints.at(i);
    return QPoint(0,0);
}

const GPS_point* GPS_leg::lastPoint() const
{
    if ( _points.count() > 0 )
        return _points.last();
    return NULL;
}

int GPS_leg::removeLastPoint()
{
    int last_distance = 0;
    int n_points = _points.count();
    if ( n_points > 0 )
    {
        GPS_point* dropped = _points.takeLast();
        _quickPoints.takeLast();
        if ( n_points > 1 )
        {
            last_distance = _points.last()->distanceTo( *dropped );
            length_mt -= last_distance;
        }
        delete dropped;
    }
    return last_distance;
}

QRectF GPS_leg::boundingRect() const
{
    return _boundingRect;
}

void GPS_leg::expandBoundingRect(double lat, double lon)
{
    if ( _boundingRect.isEmpty() )
    {
        if ( (_boundingRect == QRectF(0,0,0,0) ) )
        {
            _boundingRect.setBottomLeft( QPointF( lon, lat ) );
        }
        else
        {
            _boundingRect.setTopRight( QPointF( lon, lat ) );
            _boundingRect = _boundingRect.normalized();
        }
    }
    else
    {
        if ( lon < _boundingRect.left() )
            _boundingRect.setLeft( lon );
        if ( lat < _boundingRect.top() )
            _boundingRect.setTop( lat );
        if ( lon > _boundingRect.right() )
            _boundingRect.setRight( lon );
        if ( lat > _boundingRect.bottom() )
            _boundingRect.setBottom( lat );
    }
}

int GPS_leg::lengthMt() const
{
    return length_mt;
}

int GPS_leg::nPoints() const
{
    return _points.count();
}

QString GPS_leg::serialize() const
{
    QColor clr = color();
    return QString('"') + title().toAscii().toBase64() + '"' +
            QString(" %1 %2 %3").arg(clr.red())
                                .arg(clr.green() )
                                .arg(clr.blue( ) );
}

bool GPS_leg::unserialize(QTextStream & stream, GPS_leg* leg )
{
    QByteArray tmp;
    int red,green,blue;
    stream >> tmp;
    tmp.chop(1);
    tmp = tmp.mid(1);
    leg->setTitle( QByteArray::fromBase64(tmp ) );
    stream >> red >> green >> blue;
    leg->setColor( QColor( red, green, blue ) );
    return true;
}
